#密码实训一 古典移位密码
import string
import random,math
alpha='abcdefghijklmnopqrstuvwxyz'
Table = [['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
            ['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a'],
            ['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b'],
            ['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c'],
            ['e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd'],
            ['f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e'],
            ['g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f'],
            ['h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g'],
            ['i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
            ['j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'],
            ['k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'],
            ['l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'],
            ['m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],
            ['n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'],
            ['o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'],
            ['p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o'],
            ['q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'],
            ['r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'],
            ['s', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r'],
            ['t', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's'],
            ['u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'],
            ['v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u'],
            ['w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v'],
            ['x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w'],
            ['y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x'],
            ['z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y']]
class ClassicalCipher:
    def __init__(self,key):
        self.key=key

    def Encryp_cipher(self,s):
        message_s=[]
        try:
            t=int(self.key)
        except Exception as e:
            raise ValueError(e)
        for j in s:
            if j.isupper():
                message_s.append(chr((ord(j)-65+t)%26+65))
            elif j.islower():
                message_s.append(chr((ord(j)-97+t)%26+97))
            else:
                message_s.append(j)
        #print("k={0}:{1}".format(t,''.join(message_s)))
        eecrypted_message = ''.join(message_s).replace(' ', '')
        return eecrypted_message
    def Decryp_cipher(self,s):
        message_s=[]
        try:
            t=int(self.key)
        except Exception as e:
            raise ValueError(e)
        for j in s:
            if j.isupper():
                message_s.append(chr((ord(j)-65-t)%26+65))
            elif j.islower():
                message_s.append(chr((ord(j)-97-t)%26+97))
            else:
                message_s.append(j)
        decrypted_message = ''.join(message_s).replace(' ', '')
        return decrypted_message
        #print("k={0}:{1}".format(t,''.join(message_s)))
    def Encryp_Subcipher(self,s):#维吉尼亚
        key=self.key
        key_index=0
        message_s=[]
        for i in s:
            if i.isalpha():
                if i.isupper():
                    message_s.append((Table[alpha.find(key[key_index%len(key)])][alpha.find(i.lower())]).upper())
                else:
                    message_s.append(Table[alpha.find(key[key_index%len(key)])][alpha.find(i.lower())])
                key_index+=1
            else:
                message_s.append(i)
        eecrypted_message = ''.join(message_s).replace(' ', '')
        return eecrypted_message
        #print('密文为：{}'.format(''.join(message_s)))
    def Decryp_Subcipher(self,s):
        key=self.key
        key_index=0
        message_s=[]
        for i in s:
            if i.isalpha():
                row=alpha.find(key[key_index%len(key)])
                if i.isupper():
                    col=Table[row].index(i.upper())
                    message_s.append(alpha[col].upper())
                else:
                    col=Table[row].index(i)
                    message_s.append(alpha[col])
                key_index+=1
            else:
                message_s.append(i)
        decrypted_message = ''.join(message_s).replace(' ', '')
        return decrypted_message
        #print('密文为：{}'.format(''.join(message_s)))

    def Game(self,s):
        x=1#
        while x:
            message_s=[]
            t=random.randint(0,25)
            for j in s:
                if j.isupper():
                    message_s.append(chr((ord(j)-65-t)%26+65))
                elif j.islower():
                    message_s.append(chr((ord(j)-97-t)%26+97))
                else:
                    message_s.append(j)
            print(f'明文为：{"".join(message_s)}')
            x=int(input('找到了吗？找到请输入0，没有的话输1:')) 

    def fun_enCrypto(self,string_C):
        string_M = ''     #初始化密文
        Ek=int(self.key)
        n = 0               #提取第n列字符
        while n < Ek:
            m = 0           #第m分组
            while m < len(string_C) / Ek:  #明文长度/加密密钥  即得分组个数
                if (m * Ek+ n) < len(string_C):
                    string_M = string_M + string_C[int(m * Ek+ n)]
                    m += 1
                else :
                    break
            n += 1
        return string_M
    #Rail-Fence Cipher栅栏解密，输入加密分组中每组中的字符个数
    def fun_deCrypto(self,string_M):
        Ek=int(self.key)
        Dk = int(len(string_M) / Ek)
        string_C = ''
        yushu = len(string_M) % Ek
        steps = []
    
        if len(string_M) % Ek == 0:
            print('不存在余数')
            step = Dk
            for i in range(Ek):
                steps.append(step)
            print(steps)
    
        else:
            print('存在余数')
    
            big_step = math.ceil(len(string_M) / Ek)
            small_step = int(len(string_M) / Ek)
            for p in range(yushu):
                steps.append(big_step)
            for q in range(Ek - yushu):
                steps.append(small_step)
            print(steps)
    
        n_column = 0
        while n_column < math.ceil(len(string_M) / Ek):
            count_steps = 0
            for one_step in steps:
                if len(string_C) == len(string_M):
                    break
                else:
                    string_C += string_M[n_column + count_steps]
                    count_steps += one_step
            n_column += 1
        return string_C
